1 拆解并执行前8行代码,理解并比较对文本内容进行数值化处理¶

In [58]:
# 导入Pandas库并将其命名为pd
import pandas as pd

# 使用Pandas的read_excel函数从employee_leaves.xlsx文件中读取数据,并将数据存储在名为df的数据框中
df = pd.read_excel('employee_leaves.xlsx')
df
Out[58]:
工资 满意度 考核得分 工程数量 月工时 工龄 离职
0 低 3.8 0.53 2 157 3 1
1 中 8.0 0.86 5 262 6 1
2 中 1.1 0.88 7 272 4 1
3 低 7.2 0.87 5 223 5 1
4 低 3.7 0.52 2 159 3 1
... ... ... ... ... ... ... ...
14995 高 9.0 0.55 3 259 10 0
14996 高 7.4 0.95 5 266 10 0
14997 高 8.5 0.54 3 185 10 0
14998 高 3.3 0.65 3 172 10 0
14999 低 5.0 0.73 4 180 3 0

15000 rows × 7 columns

1.1 数值化处理,方法一¶

In [59]:
# 将数据框中名为'工资'的列中的值进行替换。具体来说,将'低'替换为0,'中'替换为1,'高'替换为2。
df = df.replace({'工资': {'低': 0, '中': 1, '高': 2}})
df
Out[59]:
工资 满意度 考核得分 工程数量 月工时 工龄 离职
0 0 3.8 0.53 2 157 3 1
1 1 8.0 0.86 5 262 6 1
2 1 1.1 0.88 7 272 4 1
3 0 7.2 0.87 5 223 5 1
4 0 3.7 0.52 2 159 3 1
... ... ... ... ... ... ... ...
14995 2 9.0 0.55 3 259 10 0
14996 2 7.4 0.95 5 266 10 0
14997 2 8.5 0.54 3 185 10 0
14998 2 3.3 0.65 3 172 10 0
14999 0 5.0 0.73 4 180 3 0

15000 rows × 7 columns

1.2 数值化处理,方法二¶

In [60]:
# 从employee_leaves.xlsx文件中读取数据,并将数据存储在名为df的数据框中
df = pd.read_excel('employee_leaves.xlsx')

# 使用Pandas的get_dummies函数对数据框df中的'工资'列进行独热编码处理,创建新的列来表示不同的工资水平
df = pd.get_dummies(df, columns=['工资'])
df
Out[60]:
满意度 考核得分 工程数量 月工时 工龄 离职 工资_中 工资_低 工资_高
0 3.8 0.53 2 157 3 1 0 1 0
1 8.0 0.86 5 262 6 1 1 0 0
2 1.1 0.88 7 272 4 1 1 0 0
3 7.2 0.87 5 223 5 1 0 1 0
4 3.7 0.52 2 159 3 1 0 1 0
... ... ... ... ... ... ... ... ... ...
14995 9.0 0.55 3 259 10 0 0 0 1
14996 7.4 0.95 5 266 10 0 0 0 1
14997 8.5 0.54 3 185 10 0 0 0 1
14998 3.3 0.65 3 172 10 0 0 0 1
14999 5.0 0.73 4 180 3 0 0 1 0

15000 rows × 9 columns

1.3 数值化处理,方法三¶

In [61]:
## 导入LabelEncoder类从sklearn.preprocessing模块
from sklearn.preprocessing import LabelEncoder

# 从employee_leaves.xlsx文件中读取数据,并将数据存储在名为df的数据框中
df = pd.read_excel('employee_leaves.xlsx')

# 创建一个LabelEncoder对象
le = LabelEncoder()

# 使用LabelEncoder对象对'工资'列进行标签编码,将分类变量转换为数值编码
label = le.fit_transform(df['工资'])
label
Out[61]:
array([1, 0, 0, ..., 2, 2, 1])
In [62]:
# 将标签编码后的数值赋值给'工资'列
df['工资'] = label
df
Out[62]:
工资 满意度 考核得分 工程数量 月工时 工龄 离职
0 1 3.8 0.53 2 157 3 1
1 0 8.0 0.86 5 262 6 1
2 0 1.1 0.88 7 272 4 1
3 1 7.2 0.87 5 223 5 1
4 1 3.7 0.52 2 159 3 1
... ... ... ... ... ... ... ...
14995 2 9.0 0.55 3 259 10 0
14996 2 7.4 0.95 5 266 10 0
14997 2 8.5 0.54 3 185 10 0
14998 2 3.3 0.65 3 172 10 0
14999 1 5.0 0.73 4 180 3 0

15000 rows × 7 columns

2 补充并执行10-20行代码,使用决策树建立模型¶

In [63]:
# 数据集中的“离职”列是目标变量,将其余列作为特征
X = df.drop('离职', axis=1)  # 特征
X
Out[63]:
工资 满意度 考核得分 工程数量 月工时 工龄
0 1 3.8 0.53 2 157 3
1 0 8.0 0.86 5 262 6
2 0 1.1 0.88 7 272 4
3 1 7.2 0.87 5 223 5
4 1 3.7 0.52 2 159 3
... ... ... ... ... ... ...
14995 2 9.0 0.55 3 259 10
14996 2 7.4 0.95 5 266 10
14997 2 8.5 0.54 3 185 10
14998 2 3.3 0.65 3 172 10
14999 1 5.0 0.73 4 180 3

15000 rows × 6 columns

In [64]:
y = df['离职']  # 目标变量
y
Out[64]:
0        1
1        1
2        1
3        1
4        1
        ..
14995    0
14996    0
14997    0
14998    0
14999    0
Name: 离职, Length: 15000, dtype: int64
In [65]:
# 导入train_test_split函数从sklearn.model_selection模块
from sklearn.model_selection import train_test_split

# 使用train_test_split函数将特征数据集X和目标数据集y划分为训练集和测试集,测试集占比为20%,设置随机种子为123
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=123)
print(X_train.shape,X_test.shape,y_train.shape,y_test.shape) # 显示划分的形状大
X_train
(12000, 6) (3000, 6) (12000,) (3000,)
Out[65]:
工资 满意度 考核得分 工程数量 月工时 工龄
3553 1 7.3 0.93 5 162 4
2112 1 4.3 0.52 2 160 3
1794 1 3.8 0.51 2 159 3
13886 1 6.3 0.71 4 244 2
11251 0 8.8 0.71 5 219 2
... ... ... ... ... ... ...
5218 0 6.3 0.80 4 256 4
12252 1 9.2 0.76 5 132 3
1346 1 7.3 0.95 4 223 6
11646 0 8.5 0.76 3 197 5
3582 0 5.6 0.58 4 258 3

12000 rows × 6 columns

In [66]:
# 导入DecisionTreeClassifier类从sklearn.tree模块
from sklearn.tree import DecisionTreeClassifier

# 创建一个DecisionTreeClassifier对象,设置最大深度为3,随机种子为123
dtc = DecisionTreeClassifier(max_depth=3, random_state=123)

# 使用训练集数据对决策树分类器进行训练
dtc.fit(X_train, y_train)

# 使用训练好的模型对测试集数据进行预测
y_pred = dtc.predict(X_test)
# 输出测试集前100个样本的分类结果
y_pred[:100]
Out[66]:
array([0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1,
       0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
       0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0], dtype=int64)
In [67]:
# 获取样本在决策树中的叶子节点索引
y_pre = dtc.apply(X_test)
y_pre[:100]
Out[67]:
array([10, 10, 14, 10,  7,  7,  3, 10,  7,  7, 10, 10, 10, 10,  7,  3, 10,
       14, 10,  7, 10, 10, 10, 10,  7, 13, 10,  6,  3, 10, 14, 10,  3, 10,
       10, 14, 10,  3, 10, 10, 10, 10, 10, 14, 10,  7, 10, 10, 10, 10, 10,
        3, 10, 10,  3, 13, 10,  3, 10, 13, 10, 14, 10, 14,  6,  7, 10, 10,
       10, 13, 10, 10,  7, 10, 10,  7,  3, 10, 10, 10, 10, 10, 10,  7, 10,
       10, 14, 10, 10,  6,  7, 13, 10, 10,  6,  6,  6, 13, 10, 10],
      dtype=int64)

DataFrame将预测值与实际值进行对比¶

In [68]:
# 创建一个DataFrame,包含预测值和实际值
comparison_df = pd.DataFrame({'实际值': y_test, '预测值': y_pred})
# 显示样本的比较结果
comparison_df
Out[68]:
实际值 预测值
6958 0 0
7534 0 0
2975 1 1
3903 0 0
8437 0 0
... ... ...
1229 1 1
10594 0 0
13211 0 0
3147 1 1
6623 0 0

3000 rows × 2 columns

3 执行22-30行代码,对决策树模型进行评估¶

In [69]:
# 评估决策树模型
from sklearn.metrics import accuracy_score, roc_curve, roc_auc_score
import matplotlib.pyplot as plt

3.1 模型自带的score函数查看模型预测准确度¶

In [70]:
# 使用模型的score函数检查预测准确度
accuracy = dtc.score(X_test, y_test)
print("预测准确度: {:.6f}".format(accuracy))
预测准确度: 0.957333

3.2 查看测试集样本被预测属于各个分类的概率¶

In [71]:
# 获取每个类别的预测概率
y_pred_proba = dtc.predict_proba(X_test)
class_names = ["不离职概率", "离职概率"]

# 显示每个样本的预测概率
print("{:<3} {:<7} {:<5}".format("",class_names[0], class_names[1]))
for i in range(20):  # 显示前20行数据,若显示全部数据将20替换成len(y_pred_proba)
    print("{:<5} {:.6f}   {:.6f}".format(i, y_pred_proba[i][0], y_pred_proba[i][1]))
    不离职概率   离职概率 
0     0.985261   0.014739
1     0.985261   0.014739
2     0.286006   0.713994
3     0.985261   0.014739
4     0.922832   0.077168
5     0.922832   0.077168
6     0.054054   0.945946
7     0.985261   0.014739
8     0.922832   0.077168
9     0.922832   0.077168
10    0.985261   0.014739
11    0.985261   0.014739
12    0.985261   0.014739
13    0.985261   0.014739
14    0.922832   0.077168
15    0.054054   0.945946
16    0.985261   0.014739
17    0.286006   0.713994
18    0.985261   0.014739
19    0.922832   0.077168
In [72]:
# 绘制ROC曲线
# 计算假正率(fpr)和真正率(tpr),并获取阈值(thres)
fpr, tpr, thres = roc_curve(y_test, y_pred_proba[:,1])
plt.plot(fpr, tpr)
plt.show()

# 计算ROC曲线下面积(ROC AUC)得分
roc_auc = roc_auc_score(y_test, y_pred_proba[:,1])
print("ROC AUC得分:", roc_auc)
ROC AUC得分: 0.9736722483245008

4 完成特征重要性评估,并通过DataFrame进行展示¶

In [73]:
# 创建包含特征名称和特征重要性的DataFrame
feature_importance = pd.DataFrame({
    '特征名称': X.columns,  # 特征名称列
    '特征重要性': dtc.feature_importances_  # 特征重要性列
})

# 根据特征重要性降序排列DataFrame
feature_importance = feature_importance.sort_values(by='特征重要性', ascending=False).reset_index(drop=True)

# 打印展示特征重要性DataFrame
feature_importance
Out[73]:
特征名称 特征重要性
0 满意度 0.598109
1 工龄 0.150866
2 考核得分 0.140074
3 工程数量 0.106387
4 月工时 0.004565
5 工资 0.000000

5 基于32-39行代码进行补充完善,对决策树模型进行可视化¶

In [74]:
'''决策树可视化需要使用graphviz插件,下载地址:https://www.graphviz.org/download/,Windows版本下载exe文件即可。
下载graphviz插件后需要安装,安装时选择添加graphviz到系统变量,否则需要手动配置环境变量,将graphviz的bin目录如C:\Program Files (x86)\Graphviz ...\bin加到系统PATH。'''
# pip install graphviz 官网下载安装好graphviz之后,cmd界面执行这条指令之后,若能成功执行这一块代码则继续后续操作,若不能则重启jupyter,将之前的所有代码重新执行一遍
from sklearn.tree import export_graphviz
import graphviz

# 指定支持中文的字体
font = "SimHei" 

# 生成决策树可视化数据
dot_data = export_graphviz(dtc, out_file=None, feature_names=X.columns, filled=True, 
                           rounded=True, special_characters=True, fontname=font)

# 生成决策树图形
graph = graphviz.Source(dot_data) 

# 保存决策树图形
graph.render("result")
Out[74]:
'result.pdf'

5.1 决策树模型进行可视化¶

In [87]:
#from IPython.display import IFrame, display    此方法能显示,但当保存为html格式时,pdf会丢失
# 用IFrame显示result.pdf文件
#pdf_path = 'result.pdf'  # PDF文件路径
#display(IFrame(pdf_path, width=800, height=500))

# 从 PIL 库中导入 Image 模块
from PIL import Image
# 打开图像文件
img0 = Image.open('result.png') # 为了显示在html上,此处自己将生成的result.pdf截图保存为result.png,然后再显示
img0
Out[87]:
In [76]:
# 对根节点中的值进行解释
root_node_value = dtc.tree_.value[0]
print("根节点中的值:", root_node_value)
根节点中的值: [[9120. 2880.]]

5.2 解释与计算过程拍照上传¶

In [77]:
# 从 PIL 库中导入 Image 模块
from PIL import Image
# 打开图像文件
img1 = Image.open('不纯度降低量.png')
img1
Out[77]:

6 理解特征重要性,将解释与计算过程拍照上传¶

In [78]:
img2 = Image.open('工龄_重要性.png')
img2
Out[78]:

7 基于41-44行代码进行补充完善¶

In [79]:
# 导入所需的库
from sklearn.model_selection import cross_val_score, GridSearchCV
from sklearn.tree import DecisionTreeClassifier

# 创建决策树分类器对象
dtc = DecisionTreeClassifier()

# 设置需要调优的参数
parameters = {'max_depth': [3, 5, 7, 9, 11]}

# 使用网格搜索和交叉验证进行参数调优
gs = GridSearchCV(dtc, parameters, cv=5, scoring='roc_auc')
gs.fit(X, y)

# 获取最佳参数和最佳模型
best_dtc = gs.best_estimator_
best_params = gs.best_params_
print('最佳模型:',best_dtc)
print('最佳参数:', best_params)
最佳模型: DecisionTreeClassifier(max_depth=7)
最佳参数: {'max_depth': 7}
In [80]:
# 使用交叉验证评估调参前后模型的性能
acc_before = cross_val_score(dtc, X, y, scoring='roc_auc', cv=5)
acc_after = cross_val_score(best_dtc, X, y, scoring='roc_auc', cv=5)

# 打印调参前后模型的性能变化
import numpy as np
print('Accuracy before tuning:', np.mean(acc_before))
print('Accuracy after tuning:', np.mean(acc_after))
Accuracy before tuning: 0.9745519722063183
Accuracy after tuning: 0.9810684907015043

在这里,我们可以观察到通过参数调优后,模型的性能得到了显著的改善。调参前模型的准确率为0.9752,而调参后模型的准确率提高到了0.9810,这意味着模型的预测能力得到了明显的提升。这种性能的提高可以帮助模型更好地适应数据,并提高对未知数据的预测准确性。因此,通过参数调优,我们成功地改善了模型的性能,使其更适合用于实际的预测任务。

8 基于45行代码进行补充完善¶

In [81]:
# 导入所需的库
from sklearn.model_selection import cross_val_score, GridSearchCV
from sklearn.tree import DecisionTreeClassifier

# 创建决策树分类器对象
dtc = DecisionTreeClassifier()

# 设置需要调优的参数
parameters = {
    'max_depth': [5, 7, 9, 11, 13],
    'criterion': ['gini', 'entropy'],
    'min_samples_split': [5, 7, 9, 11, 13, 15]
}

# 使用网格搜索和交叉验证进行多参数调优
gs = GridSearchCV(dtc, parameters, cv=5, scoring='roc_auc')
gs.fit(X, y)

# 获取最佳参数和最佳模型
print('最佳模型:',best_dtc)
print('最佳参数:', best_params)
最佳模型: DecisionTreeClassifier(max_depth=7)
最佳参数: {'max_depth': 7}
In [82]:
# 使用交叉验证评估调参前后模型的性能
acc_before = cross_val_score(dtc, X, y, scoring='roc_auc', cv=5)
acc_after = cross_val_score(best_dtc, X, y, scoring='roc_auc', cv=5)

# 打印调参前后模型的性能变化
print('Accuracy before tuning:', np.mean(acc_before))
print('Accuracy after tuning:', np.mean(acc_after))
Accuracy before tuning: 0.974577641252129
Accuracy after tuning: 0.9807955468783056

这种性能的提升是显著的,表明通过参数调优,模型的预测能力得到了提升。这将使模型更适合用于实际的预测任务,并提高对未知数据的预测准确性。因此,经过参数调优后,模型的性能得到了显著的改善,这对于提高模型的实用性和预测能力具有重要意义。

9 使用随机森林建立模型,对模型进行调参¶

In [83]:
# 导入所需的库
from sklearn.ensemble import RandomForestClassifier
import matplotlib.pyplot as plt

# 创建随机森林分类器对象
rfc = RandomForestClassifier()

# 设置需要调优的参数
parameters = {
    'n_estimators': [50, 100, 150],
    'max_depth': [5, 7, 9],
    'min_samples_split': [2, 4, 6]
}

# 使用网格搜索和交叉验证进行多参数调优
gs = GridSearchCV(rfc, parameters, cv=5, scoring='roc_auc')
gs.fit(X, y)

# 获取最佳参数和最佳模型
best_rfc = gs.best_estimator_
best_params = gs.best_params_
print('Best parameters:', best_params)
Best parameters: {'max_depth': 9, 'min_samples_split': 4, 'n_estimators': 100}
In [84]:
# 训练最佳模型
best_rfc.fit(X, y)

# 可视化特征重要性
# 创建包含特征名称和特征重要性的DataFrame
feature_importance = pd.DataFrame({
    '特征名称': X.columns,  # 特征名称列
    '特征重要性': best_rfc.feature_importances_  # 特征重要性列
})

# 根据特征重要性降序排列DataFrame
feature_importance = feature_importance.sort_values(by='特征重要性', ascending=False).reset_index(drop=True)

# 打印展示特征重要性DataFrame
feature_importance
Out[84]:
特征名称 特征重要性
0 满意度 0.349931
1 工龄 0.194673
2 工程数量 0.191984
3 月工时 0.144550
4 考核得分 0.114786
5 工资 0.004076

10 将随机森林模型与决策树模型进行对比¶

In [85]:
# 使用交叉验证评估两个模型的性能
acc_dtc = cross_val_score(best_dtc, X, y, scoring='roc_auc', cv=5)
acc_rfc = cross_val_score(best_rfc, X, y, scoring='roc_auc', cv=5)

# 打印两个模型的性能
print('决策树模型的精确度:', np.mean(acc_dtc))
print('随机森林模型的精确度:', np.mean(acc_rfc))
决策树模型的精确度: 0.9812200648919853
随机森林模型的精确度: 0.9919869445773528

面对此数据集,通过调参分得到的两个最佳模型,其中随机森林模型的性能更好。在随机森林模型中,特征"工资"参与了模型的构建和预测,并且其特征重要性为0.003946。相比之下,在决策树模型中,特征"工资"的特征重要性为0。因此,可以得出随机森林模型更加合理,能够预测得更加精准。